#ifndef _UDSCOMMON_H_
#define _UDSCOMMON_H_
#include <functional>
#include <memory>
#include <vector>
#include <sys/uio.h>
#include <iostream>
#include <functional>


#if 0
#include <android/log.h>
#define TAG "uds_SunloginClient"
#define WriteLog(LEVEL, args...) __android_log_print(ANDROID_LOG_INFO, TAG, ##args);
#endif

#define MAX_PACKS_NUM 10
#define MAX_MSG_LEN 1024*512

typedef struct _UdsHead
{
    unsigned char mark[4];  ///< 0xaa 0xbb 0xcc 0xdd 
	int cmd;
	int packCount;
	unsigned int size[MAX_PACKS_NUM];
	int crc;
}UdsHead, *p_UdsHead;

typedef struct _UdsPack
{
   	UdsHead head; 				///< buffer
	std::vector<iovec> bufvec; 	///< 发送包 适用于writev
	int aimlen;					///< 总长度
}UdsPack, *p_UdsPack;

typedef struct _UdsHandler
{
    int fd;                             ///< 套接字
    int cmd;                            ///< 信令编号
    int maxMsgLen;                      ///< 消息长度
    int msgLen;                         ///< 消息长度
    char *pMsg;                         ///< 消息体起始地址
	int headLen;
	char *pHead;
    void *packsAddr[MAX_PACKS_NUM];
	unsigned int packsSize[MAX_PACKS_NUM];
    int packsCount;
	bool isLongLink;
	void *pObj;
}UdsHandler, *p_UdsHandler;


typedef void (*udsFunc)(p_UdsHandler pHandler);
typedef void (*stdUdsFunc)(p_UdsHandler pHandler);
/* typedef std::function<void(p_UdsHandler pHandler)> stdUdsFunc; */

/* typedef std::function<void(p_UdsHandler pHandler, void * pUserData)> stdUdsFuncArgs; */

struct udsCommon
{
	static p_UdsHandler creatHandler();
	static void destroyHandler(p_UdsHandler pHandler);
	static void setNoBlocking(int sock);

    static int createListenUds(const char *path);
    static int createListenTcp(const int port);
	static int listenAccpet(int fd);

	static int tryGetConnectedTcpFd(int &sockfd, const char *ip, int port);
	static int tryGetConnectedUdsFd(int &sockfd, const char *paths);

	/**
	 * @brief 尝试读取 MaxLen 长度数据
	 * 		\li 读取缓冲区读取完毕后返回
	 * 
	 * @param socketfd fd
	 * @param buff 数据接收指针
	 * @param maxlen 数据接收buff最大长度
	 * @param timout poll 阻塞时间 
	 * @return int 读取长度
	 */
	static int getDatas(int socketfd, unsigned char *buff, int maxlen, int timout);
	static int getUdsPacks(p_UdsHandler pHandler, int timout);

	static std::unique_ptr<UdsPack> makeSendPack(int cmd, void **addr, size_t *frame_size, int pack_count);
	static int sendPacks(int fd, int cmd, void **addr, size_t *frame_size, int pack_count);
	static int sendMsg(int fd, int cmd, void *msg, int msgLen);

    static unsigned int crc_make(unsigned char *ptr, int len, unsigned int firstcrc);
	static size_t getBufClusterSize(size_t len);
	static bool mallocHandler(p_UdsHandler pHandler, size_t len);
};

#endif //_UDSCOMMON_H_
